#ifndef TIMERTHREAD_H
#define TIMERTHREAD_H

#include <iostream>
#include <thread>
#include <chrono>
#include <vector>
#include <functional>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <algorithm>

class TimerThread
{
public:
    void stop()
    {
        stopFlag = true;
        m_cond.notify_all();
        m_timerThread.join();
        m_workerThread.join();
    }
    static TimerThread *getInstance()
    {
        static TimerThread timer;
        return &timer;
    }

    void addTask(std::string devId, std::function<void()> task, std::chrono::seconds period)
    {
        long long timeStamp = std::chrono::duration_cast<std::chrono::seconds>(
                                  std::chrono::steady_clock::now().time_since_epoch())
                                  .count() +
                              period.count();
        // bool flag = false;
        std::unique_lock<std::mutex> lock(m_mutex);
        m_task.push_back(Task(devId, timeStamp, task, period, false)); // 使用完整构造函数初始化 Task 对象
    }
    void addOneTask(std::function<void()> taskFunc)
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        taskFunc();
    }

    void deleteTask(std::string devId)
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        auto result = std::find_if(m_task.begin(), m_task.end(),
                                   [&devId](const Task &task)
                                   { return task.isMatchingDevId(devId); });
        // 仿函数，用于寻找指定的设备ID，删除任务
        if (result != m_task.end())
        {
            // std::cout << "找到了指定的元素，删除" << std::endl;
            while (result->isExecuting)
            {
                NOTICE("任务正在执行，等待任务执行完成");
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
            }

            m_task.erase(result);
        }
        else
        {
            // 没找到
        }
    }
    void clearTask()
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        m_task.clear();
    }

    void start()
    {
        stopFlag = false;

        if (!m_timerThread.joinable())
        {
            m_timerThread = std::thread([this]()
                                        { timerLoop(); });
        }

        if (!m_workerThread.joinable())
        {
            m_workerThread = std::thread([this]()
                                         { workerLoop(); });
        }
    }

private:
    void timerLoop()
    {
        while (!stopFlag)
        {
            // 周期性获取任务是否到期
            auto now = std::chrono::duration_cast<std::chrono::seconds>(
                           std::chrono::steady_clock::now().time_since_epoch())
                           .count();

            {
                std::function<void()> pushTask;
                {
                    std::unique_lock<std::mutex> lock(m_mutex);
                    for (auto &task : m_task)
                    {
                        if (now >= task.nextTime) // 如果当前时间戳＞任务的下次执行时间
                        {
                            pushTask = task.task;
                            task.nextTime += task.period.count(); // 更新任务的下次执行时
                        }
                    }
                }
                {
                    std::unique_lock<std::mutex> lock(m_dequeMutex);
                    m_taskQueue.push_front(pushTask); // 把任务放到任务队列中
                    m_cond.notify_one();              // 通知工作线程，有任务了
                }
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
        }
    }

    void workerLoop()
    {
        while (!stopFlag)
        {
            std::function<void()> task;
            {
                std::unique_lock<std::mutex> lock(m_dequeMutex);

                auto timeout = std::chrono::milliseconds(500); // 设置等待的时间
                m_cond.wait_for(lock, timeout, [this]()
                                { return !m_taskQueue.empty() || stopFlag; });
                if (!m_taskQueue.empty())
                {
                    task = m_taskQueue.front(); // 取出任务
                    m_taskQueue.pop_front();    // 删除任务
                }
            }
            if (task)
            {
                // 在执行任务前设置 isExecuting 为 true
                {
                    std::unique_lock<std::mutex> lock(m_mutex);
                    auto it = std::find_if(m_task.begin(), m_task.end(),
                                           [task](const Task &tptr)
                                           { return tptr.task.target<void()>() == task.target<void()>(); });
                    if (it != m_task.end())
                    {
                        it->isExecuting = true;
                    }
                }

                task(); // 执行任务
                // 在任务执行完成后将 isExecuting 设置为 false
                {
                    std::unique_lock<std::mutex> lock(m_mutex);
                    auto it = std::find_if(m_task.begin(), m_task.end(),
                                           [task](const Task &tptr)
                                           { return tptr.task.target<void()>() == task.target<void()>(); });
                    if (it != m_task.end())
                    {
                        it->isExecuting = false;
                    }
                }
            }
        }
    }

    struct Task
    {
        std::string devId;           // 设备ID
        long long nextTime;          // 记录下次到期时间
        std::function<void()> task;  // 任务
        std::chrono::seconds period; // 周期
        bool isExecuting = false;    // 添加一个标记，表示任务是否正在执行
        Task(std::string devId, long long nextTime, std::function<void()> task, std::chrono::seconds period, bool isExecuting)
            : devId(devId), nextTime(nextTime), task(task), period(period), isExecuting(isExecuting)
        {
        }
        bool isMatchingDevId(const std::string &targetDevId) const
        {
            return devId == targetDevId;
        }
        bool operator<(const Task &other) const
        {
            return nextTime > other.nextTime; // 重载比较操作符，使得最早到期的任务优先
        }
    };

    bool stopFlag = false;
    std::vector<Task> m_task;                      // 任务列表
    std::thread m_timerThread;                     // 定时器线程
    std::thread m_workerThread;                    // 工作线程
    std::deque<std::function<void()>> m_taskQueue; // 周期性任务队列
    std::mutex m_mutex;                            // 用于保护任务队列的互斥锁
    std::mutex m_dequeMutex;                       // 用于通知工作线程的互斥锁
    std::condition_variable m_cond;                // 条件变量
    std::deque<std::function<void()>> m_oneTask;   // 一次性任务队列
};
#endif // TIMER_H
int main()
{
    TimerThread::getInstance()->addOneTask([]()
                                           { std::cout << "hello world" << std::endl; });
    TimerThread::getInstance()->addTask(
        "devId", []()
        { std::cout << "hello world" << std::endl; },
        std::chrono::seconds(5));
    TimerThread::getInstance()->start();
    while (1)
    {
        /* code */
    }
}